package multicast;

import handlers.MessageHandler;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.ArrayList;

import constants.NetworkConstants;

public class MultiCastCommsManager extends Thread {
	
	private int portNumber ;
	private String groupAddress;
	private MulticastSocket socket;
	private byte[] buffer;
	private ArrayList<MessageHandler> messageHandlerList ;
	//Multicast manager is used to handle FileStoreAnnouncements
	//Also used to receive update announcements.
	public MultiCastCommsManager(){
		this.portNumber = NetworkConstants.DEFAULT_ANNOUNCEMENT_PORT;
		this.groupAddress = NetworkConstants.DEFAULT_ANNOUNCEMENT_GROUP;
		try {
			socket = new MulticastSocket(this.portNumber);
			if(socket !=null){
				socket.joinGroup(InetAddress.getByName(this.groupAddress));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.buffer = new byte[NetworkConstants.DATAGRAM_SIZE] ;
		this.messageHandlerList = new ArrayList<MessageHandler>();
		this.start();
	}
	public MultiCastCommsManager(int portNumber) {
		this.portNumber = portNumber;
		this.groupAddress = NetworkConstants.DEFAULT_ANNOUNCEMENT_GROUP;
		try {
			socket = new MulticastSocket(this.portNumber);
			if(socket !=null){
				socket.joinGroup(InetAddress.getByName(this.groupAddress));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		this.buffer = new byte[NetworkConstants.DATAGRAM_SIZE] ;
		this.messageHandlerList = new ArrayList<MessageHandler>();
		this.start();
	}
	public void addMessageHandler(MessageHandler mh){
		this.messageHandlerList.add(mh) ;
	}
	@Override
	public void run() {
		
		while(this.socket != null){
			try {
				DatagramPacket packet = new DatagramPacket(this.buffer, buffer.length);
				socket.receive(packet);
				//find the null node				
				String data = new String(packet.getData()) ;
				data = data.trim();			
				synchronized (this.messageHandlerList) {
					System.out.println(messageHandlerList.size());
					for(int i = 0; i < messageHandlerList.size(); i++){
						System.out.println("Calling message handler");
						this.messageHandlerList.get(i).handleMessage(data);
					}
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			}
			this.buffer = new byte[NetworkConstants.DATAGRAM_SIZE];
		}
	}
}
